package org.example.service.imp;

import org.example.dao.UserDao;
import org.example.domain.Ticket;
import org.example.domain.User;
import org.example.otherObject.EmailParam;
import org.example.service.UserService;
import org.example.util.CommonParam;
import org.example.util.HutoolUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.GetMapping;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

@Service
public class UserServiceImp implements UserService {
    @Autowired
    private UserDao userDao;
    @Autowired
    private HutoolUtil hutoolUtil;
    @Override
    public int importAll(List<User> userList) {
        return userDao.importAll(userList);
    }

    @Override
    public User searchById(int id) {
        return userDao.searchById(id);
    }
    public Map<String,String> judgeRegisterUserIsEmpty(User user){
        if (user == null) return null;
        Map<String,String> result = new HashMap<>();
        String username = user.getUsername();
        if (username == null || username.equals("") ||username.equals(" ")){
            result.put(CommonParam.USERNAME_ERROR,"账户不能为空");
            return result;
        }
        String password = user.getPassword();
        if (password == null || password.equals("") || password.equals(" ")){
            result.put(CommonParam.PASSWORD_ERROR,"密码不能为空");
            return result;
        }
        String email = user.getEmail();
        if (email == null || !email.contains("@")  || email.equals(" ")|| email.equals("")){
            result.put(CommonParam.EMAIL_ERROR,"邮箱填写错误");
            return result;
        }
        result.put(CommonParam.VERIFY_FINISH,"ok");
        return result;
    }
    public void perfectUserInfo(User user){
        //完整注册用户信息
        String salt = hutoolUtil.randomString(4);
        user.setSalt(salt);
        String md5 = hutoolUtil.md5EncryptHex(user.getPassword(), user.getSalt());
        user.setPassword(md5);
        user.setType((byte)0);
        //需要邮件激活
        user.setStatus((byte)0);
        String activationCode = hutoolUtil.randomString();
        user.setActivationCode(activationCode);
        user.setHeaderUrl("/img/header.png");
    }
    @Value("${community.path}")
    private String communityPath ;

    /**
     *
     * @param user
     * @return
     */
    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    private TransactionDefinition transactionDefinition;

    /**
     * 这里需要手动处理一下事务 因为 我在完善数据时不能确认qq邮箱是否存在(需要与qq邮箱服务器做处理 麻烦)
     * 所以我们需要先发送邮件才能判断qq邮箱是否存在(因为邮件的发送需要一个userid  这个必须要先存储才有)
     * 这里使用手动调提交事务  不适用声明事务
     * @param user
     * @return
     */
    @Override
    public Map<String,String> registerUser(User user) {
        Map<String, String> result = judgeRegisterUserIsEmpty(user);
        if (result == null || !result.containsKey(CommonParam.VERIFY_FINISH)){
            return result;
        }

        //需要判断信息是否重复  包括username 和 email
        int usernameCount = searchCountByUserName(user.getUsername());
        if (usernameCount>0){
            result.put(CommonParam.USERNAME_ERROR,"用户名重复");
            if (result.containsKey(CommonParam.VERIFY_FINISH)) result.remove(CommonParam.VERIFY_FINISH);
            return result;
        }
        int emailCount = searchCountByEmail(user.getEmail());
        if (emailCount>0){
            result.put(CommonParam.EMAIL_ERROR,"邮箱已注册");
            if (result.containsKey(CommonParam.VERIFY_FINISH)) result.remove(CommonParam.VERIFY_FINISH);
            return result;
        }
        //不为空 不重复 可以完善信息
        perfectUserInfo(user);
        //新的用户 需要注册  需要将信息完整化  然后发送邮件让用户激活(user中存在一个字段status  需要用户确认 )
        TransactionStatus transaction = null;
        try {
            //这里相当于是记录一下状态 然后还原状态
            transaction = dataSourceTransactionManager.getTransaction(transactionDefinition);
            int i = saveOne(user);
            //发送邮件用户激活  需要发送一个邮件 email有  邮件里面需要发送一笔请求到我们的服务 就是改一下用户的status   请求的参数需要id 激活码
            EmailParam emailParam = new EmailParam();
            emailParam.setTo(user.getEmail());
            emailParam.setTitle("注册确认");
            //因为这里邮件是发送给qq邮箱服务器  这里写相对路径 相对于qq邮箱  我们这个项目 没有一个公网ip 都是局域网  就访问当前工程就算啦
            emailParam.setContext("/mail/activation.html");
            emailParam.setUsername(user.getUsername());
            emailParam.setId(user.getId());
            //我们服务端处理一个激活的请求
            emailParam.setUrl(communityPath+"/user/activation");
            emailParam.setActivationCode(user.getActivationCode());
            hutoolUtil.sendMail(emailParam,true);
            dataSourceTransactionManager.commit(transaction);
        }catch (Exception e){
            result.put(CommonParam.EMAIL_ERROR,"邮箱不存在");
            if (result.containsKey(CommonParam.VERIFY_FINISH)) result.remove(CommonParam.VERIFY_FINISH);
            e.printStackTrace();
            dataSourceTransactionManager.rollback(transaction);
            return result;
        }
        //能走到这里 信息 都没有问题 result中就只有key = ok value = ok
        return result;
    }

    @Override
    public int searchCountByUserName(String username) {
        return userDao.searchCountByUsername(username);
    }

    @Override
    public int searchCountByEmail(String email) {
        return userDao.searchCountByEmail(email);
    }

    @Override
    public int saveOne(User user) {
        return userDao.saveOne(user);
    }

    /**
     *
     * @param id
     * @param activationCode
     * @return  0代表当前id的用户不存在 1代表重复激活 2代表激活码不正确 3成功激活
     */
    @Override
    public String activationUser(int id,String activationCode) {
        User user = searchById(id);
        if (user == null) return "当前用户不存在";
        if (!user.getActivationCode().equals(activationCode)) return "重复激活";
        if (user.getStatus() == 1) return "激活码不正确";
        int i = userDao.activationUser(id);
        String message = null;
        if (i>=1) message = "激活成功";
        if (i<=0) message = "激活失败";
        return message;
    }

    /**
     *
     * @param id 可以不传  用username查 默认给0
     * @param username
     * @return
     */
    @Override
    public User search(int id, String username) {
        if (id<0 || hutoolUtil.stringIsEmpty(username)) return null;
        return userDao.search(id,username);
    }
    @Autowired
    private TicketServiceImp ticketServiceImp;
    @Override
    public Map<String, String> login(String username, String password,boolean rememberMe) {
        Map<String,String> result = new HashMap<>();
        if (hutoolUtil.stringIsEmpty(username) || hutoolUtil.stringIsEmpty(password)){
            result.put(CommonParam.USERNAME_OR_PASSWORD_ERROR,"用户名或者密码不能为空");
        }
        User user = search(0, username);
        if (user == null){
            result.put(CommonParam.USERNAME_ERROR,"用户不存在");
            return result;
        }
        String temp = user.getPassword();
        String md5 = hutoolUtil.md5EncryptHex(password, user.getSalt());
        if (!temp.equals(md5)){
            result.put(CommonParam.PASSWORD_ERROR,"密码错误");
            return result;
        }
        if (user.getStatus()==0){
            result.put(CommonParam.USER_ACTIVATION_FAILED,"当前用户没有激活");
            return result;
        }
        //登录成功 存储一个登录凭证
        Ticket ticket = new Ticket();
        ticket.setUserId(user.getId());
        ticket.setStatus((byte)1);
        ticket.setExpired(new Date(System.currentTimeMillis()+(rememberMe?CommonParam.REMEMBER_EXPIRED_TIME:CommonParam.NORMAL_EXPIRED_TIME)));
        ticket.setTicket(hutoolUtil.randomString(6));
        result.put(CommonParam.TICKET_SYMBOL,ticket.getTicket());
        int i = ticketServiceImp.saveOne(ticket);
        result.put(CommonParam.VERIFY_FINISH,CommonParam.VERIFY_FINISH);
        return result;
    }

    @Override
    public int updateHeaderUrlById(int userId,String headerUrl) {
        if (userId<=0) return 0;
        return userDao.updateHeaderUrlById(userId,headerUrl);
    }

    @Override
    public int updatePasswordById(int id, String password) {
        if (id <=0 || hutoolUtil.stringIsEmpty(password)) return 0;
        return userDao.updatePasswordById(id,password);
    }

    @Override
    public User searchByUsername(String username) {
        if (hutoolUtil.stringIsEmpty(username)) return null;
        return userDao.searchByUsername(username);
    }

    @Override
    public List<User> selectUsers(Collection<Object> ids,int page,int limit) {
        if (ids ==null || ids.size()<=0) return null;
        return userDao.selectUsers(ids,page,limit);
    }
}
